#!/usr/bin/env python3
# -*- coding: utf-8 -*-
########################################################################
#
# Copyright (c) 2023 Zhiyong Lin. All Rights Reserved
#
########################################################################
'''
@File    :   logger.py
@Time    :   2025/10/20 16:02:55
@Author  :   lzy2lcy 
@Version :   1.0
@Desc    :   封装日志模块
'''

import os
import json
import logging
from logging import FileHandler, LoggerAdapter
from datetime import datetime
import config
from utils import const

class DefinedFileHandler(FileHandler):
    '''自定义日志文件处理

    logging进程不安全,默认的rotateHandler会因此表现异常
    使用日期分割日志文件
    '''
    def __init__(self, filename, mode='a', encoding=None, delay=False):
        '''
        FileHandler主要实例参数:
            self.baseFilename = os.path.abspath(filename)
            self.mode = mode
            self.encoding = encoding
            self.stream = open(self.baseFilename...)
        '''
        # 文件名 filename.%Y-%m-%d
        filename = '{filename}.{date_suffix}'.format(
            filename=filename,
            date_suffix=datetime.now().strftime(const.DAY_FORMAT)
        )
        super().__init__(filename, mode, encoding, delay)
    
    def create_new_basefile(self, new_suffix):
        '''Handler更新日志文件
        '''
        self.baseFilename = '{filename}.{new_suffix}'.format(
            filename=self.baseFilename.rsplit('.', 1)[0],
            new_suffix=new_suffix
        )
        if self.stream:
            # 关闭老文件流
            self.stream.close()
            # 指向新文件
            self.stream = self._open()

    def emit(self, record):
        '''handler处理文件函数
        '''
        new_suffix = datetime.now().strftime(const.DAY_FORMAT)
        # 新日期需要换文件
        if not self.baseFilename.endswith(new_suffix):
            self.create_new_basefile(new_suffix)
        super().emit(record)   


class DefinedLogAdapter(LoggerAdapter):
    '''自定义日志消息处理

    实现日志信息主体json化
    '''

    def process(self, msg, kwargs):
        '''msg信息json化处理
        '''
        # exc_info是logging中的关键字，要剔除出来
        if 'exc_info' in kwargs:
            exc_info = kwargs.pop('exc_info')
        else:
            exc_info = ''
        kwargs['msg'] = msg
        return json.dumps(kwargs), {'exc_info': exc_info} if exc_info else {}


def get_logger(name):
    logger = logging.getLogger(name)
    # 日志等级
    level = logging.DEBUG if config.DEBUG else logging.INFO
    logger.setLevel(level)
    # 日志格式
    fmt = '[%(asctime)s][%(levelname)s][%(filename)s::%(funcName)s:%(lineno)d] %(message)s'
    # 日志输出
    if not logger.handlers:
        log_filename = os.path.join(
            config.LOG_DIR,
            'mcp_{name}.log'.format(name=name)
        )
        formatter = logging.Formatter(fmt)
        # 文件输出
        handler = DefinedFileHandler(log_filename)
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        # 测试环境，标准输出(生产环境也加上吧, 方便问题排查)
        handler_stdout = logging.StreamHandler()
        handler_stdout.setFormatter(formatter)
        logger.addHandler(handler_stdout)
        logger.propagate = False

    logger = DefinedLogAdapter(logger, extra=None)
    return logger
